"""
A module with tests of storage pools
"""
import unittest as ut
import threading
import time

import vdsClient as vdsc
import basicVdsTest as vdst
import agentUtils
from confUtils import Validate
from storageConnectionTestUtils import eStorageType, disconnectFromStorage, connectToStorage, validateConnections, CONNECTIONS_OPTION_DEFAULT
from storageDomainTestUtils import eDomainClass, generateDomainTargets, destroyDomainTargets
from enum import Enum
from threading import Thread
from testUtils import cleanVdsm

ePoolStatus = Enum(
    Connected="connected"
)
__commonConfig__ = {
    "VdsUri1" : {"default" : "http://server:54321"},
    "Connections" : {"default" : CONNECTIONS_OPTION_DEFAULT, "validator" : validateConnections},
    "HostID1" : {"default" : 7, "validator" : Validate.int},
    "Pool1Key" : {"default" : "NFSKEY"},
    "DomainClass1" : {"default" : "data", "validator" : eDomainClass.parse},
    "Domain1" : {"default" : "GUID, GUID", "validator" : Validate.list},
    "StorageType1": {"default" : "nfs", "validator" : eStorageType.parse},
}

class StoragePoolTestCaseBase(vdst.BasicVDSTest):
    """
    Contains common factors shared by all the storage pool test cases.
    """
    #For convenience. I didn't put it in the base class because I didn't want to commit.
    mycfg = property(lambda self: self.cfg[self.__class__.__name__])
    @classmethod
    def getConfigTemplate(cls):
        return { cls.__name__ : __commonConfig__ }

    def setUp(self):
        #Setup client
        self.client = vdsc.VDSClient()
        self.client.setURI(self.mycfg["VdsUri1"])

        #Make sure env is clean
        resp = self.assertVdscOK(self.client.getConnectedStoragePoolsList())
        self.assertTrue(len(resp['poollist']) == 0, "VDSM is connected to a pool. Dirty env. Bailing out.")

        #Handle storage configuration
        connectToStorage(self.client, self.mycfg["Connections"])

    def tearDown(self):
        cleanVdsm(self.client, self.mycfg["HostID1"], self.mycfg["Connections"])

class CreateStoragePoolManyDomains(StoragePoolTestCaseBase):
    """
    Create a storage pool with three domains.
    """
    @classmethod
    def getConfigTemplate(cls):
        myExtraConf = {cls.__name__ : {
            "DomainClass2" : {"default" : "data", "validator" : eDomainClass.parse},
            "Domain2" : {"default" : "GUID, GUID", "validator" : Validate.list},
            "StorageType2": {"default" : "nfs", "validator" : eStorageType.parse},
            "DomainClass3" : {"default" : "data", "validator" : eDomainClass.parse},
            "Domain3" : {"default" : "GUID, GUID", "validator" : Validate.list},
            "StorageType3": {"default" : "nfs", "validator" : eStorageType.parse},
            }
        }
        myExtraConf[cls.__name__].update(__commonConfig__)
        return myExtraConf

    def setUp(self):
        StoragePoolTestCaseBase.setUp(self)

        #setup test variables
        domains = [self.mycfg["Domain1"], self.mycfg["Domain2"], self.mycfg["Domain3"]]
        self.domainTarget1, self.domainTarget2, self.domainTarget3 = generateDomainTargets(self.client, self.mycfg["Connections"], domains)

        self.sdUUID1 = self.client.newUUID()
        self.sdUUID2 = self.client.newUUID()
        self.sdUUID3 = self.client.newUUID()
        self.spUUID = self.client.newUUID()

        #Create the tmp domains
        self.assertVdscOK(
            self.client.createStorageDomain(self.mycfg["StorageType1"], self.sdUUID1,
                "Aglaia", self.domainTarget1, self.mycfg["DomainClass1"]
            )
        )
        self.assertVdscOK(
            self.client.createStorageDomain(self.mycfg["StorageType2"], self.sdUUID2,
                "Euphrosyne", self.domainTarget2, self.mycfg["DomainClass2"]
            )
        )
        self.assertVdscOK(
            self.client.createStorageDomain(self.mycfg["StorageType3"], self.sdUUID3,
                "Thalia", self.domainTarget3, self.mycfg["DomainClass3"]
            )
        )

    def test(self):
        expectedPoolName = "The Three Graces"
        self.assertVdscOK(
            self.client.createStoragePool(self.spUUID, expectedPoolName, self.sdUUID1, [self.sdUUID1, self.sdUUID2, self.sdUUID3], 1)
            )

        self.assertVdscOK(
            self.client.connectStoragePool(self.spUUID, self.mycfg["HostID1"], self.mycfg["Pool1Key"])
            )

        info = self.assertVdscOK(
            self.client.getStoragePoolInfo(self.spUUID))

        poolStatus = info["info"]["pool_status"]
        self.assertEquals(poolStatus, ePoolStatus.Connected)

        expectedDomInfo = {self.sdUUID1 : {'status': 'Attached'},
                           self.sdUUID2 : {'status': 'Attached'},
                           self.sdUUID3 : {'status': 'Attached'}}

        self.assertEquals(info["dominfo"], expectedDomInfo)

        poolName = info['info']['name']
        self.assertEquals(poolName, expectedPoolName)

class DeactivateMaster(StoragePoolTestCaseBase):
    """
    Deactivate master SD with wrong master version.
    """
    @classmethod
    def getConfigTemplate(cls):
        myExtraConf = {cls.__name__ : {
            "DomainClass2" : {"default" : "data", "validator" : eDomainClass.parse},
            "Domain2" : {"default" : "GUID, GUID", "validator" : Validate.list},
            "StorageType2": {"default" : "nfs", "validator" : eStorageType.parse},
            "DomainClass3" : {"default" : "data", "validator" : eDomainClass.parse},
            "Domain3" : {"default" : "GUID, GUID", "validator" : Validate.list},
            "StorageType3": {"default" : "nfs", "validator" : eStorageType.parse},
            }
        }
        myExtraConf[cls.__name__].update(__commonConfig__)
        return myExtraConf

    def setUp(self):
        StoragePoolTestCaseBase.setUp(self)

        #setup test variables
        domains = [self.mycfg["Domain1"], self.mycfg["Domain2"], self.mycfg["Domain3"]]
        self.domainTarget1, self.domainTarget2, self.domainTarget3 = generateDomainTargets(self.client, self.mycfg["Connections"], domains)

        self.sdUUID1 = self.client.newUUID()
        self.sdUUID2 = self.client.newUUID()
        self.sdUUID3 = self.client.newUUID()
        self.spUUID = self.client.newUUID()

        #Create the tmp domains
        self.assertVdscOK(
            self.client.createStorageDomain(self.mycfg["StorageType1"],
                self.sdUUID1, "Nif-nif", self.domainTarget1,
                self.mycfg["DomainClass1"]
            )
        )
        self.assertVdscOK(
            self.client.createStorageDomain(self.mycfg["StorageType2"],
                self.sdUUID2, "Naf-naf", self.domainTarget2,
                self.mycfg["DomainClass2"]
            )
        )
        self.assertVdscOK(
            self.client.createStorageDomain(self.mycfg["StorageType3"],
                self.sdUUID3, "Nuf-nuf", self.domainTarget3,
                self.mycfg["DomainClass3"]
            )
        )

        PoolName = "The Three Piglets"
        self.master = self.sdUUID1
        self.masterVersion = 4
        self.assertVdscOK(
            self.client.createStoragePool(self.spUUID, PoolName,
                self.master, [self.sdUUID1, self.sdUUID2, self.sdUUID3],
                self.masterVersion
            )
        )

        self.assertVdscOK(
            self.client.connectStoragePool(self.spUUID, self.mycfg["HostID1"],
                self.mycfg["Pool1Key"])
            )

        #start tmp spm
        resp = self.assertVdscOK(
            self.client.spmStart(self.spUUID, -1, -1, -1, False)
        )
        taskid = resp['uuid']

        self.assertVdscTaskOK(self.client, taskid)

        self.assertVdscOK(
            self.client.activateStorageDomain(self.sdUUID1, self.spUUID)
        )

        self.assertVdscOK(
            self.client.activateStorageDomain(self.sdUUID2, self.spUUID)
        )

        self.assertVdscOK(
            self.client.activateStorageDomain(self.sdUUID3, self.spUUID)
        )


    def lastMaster(self):
        """
        Should fail for master domain
        """
        invalidMasterVer = self.masterVersion - 1

        self.assertVdscOK(
            self.client.deactivateStorageDomain(self.sdUUID2, self.spUUID,
                vdst.BLANK_UUID, 0
            )
        )

        self.assertVdscOK(
            self.client.deactivateStorageDomain(self.sdUUID3, self.spUUID,
                vdst.BLANK_UUID, 0
            )
        )

        self.assertVdscOK(
            self.client.deactivateStorageDomain(self.master, self.spUUID,
                vdst.BLANK_UUID, 0
            )
        )

        response = self.assertVdscOK(
            self.client.getStoragePoolInfo(self.spUUID))

        info = response['info']
        newMasterVer = int(info['master_ver'])
        self.assertEqual(self.masterVersion, newMasterVer)


    def sameMasterVersion(self):
        """
        Should fail for master domain
        """

        masterVer = self.masterVersion

        self.assertVdscFail(
            self.client.deactivateStorageDomain(self.master, self.spUUID,
                self.sdUUID2, masterVer
            )
        )

        response = self.assertVdscOK(
            self.client.getStoragePoolInfo(self.spUUID))

        info = response['info']
        newMasterVer = int(info['master_ver'])
        self.assertEqual(self.masterVersion, newMasterVer)


    def higherMasterVersion(self):
        """
        Should succeed for master domain
        """

        higherMasterVer = self.masterVersion + 1

        self.assertVdscOK(
            self.client.deactivateStorageDomain(self.master, self.spUUID,
                self.sdUUID2, higherMasterVer
            )
        )

        response = self.assertVdscOK(
            self.client.getStoragePoolInfo(self.spUUID)
        )

        info = response['info']
        newMasterVer = int(info['master_ver'])
        self.assertNotEqual(self.masterVersion, newMasterVer)

class RepoStats(StoragePoolTestCaseBase):
    """
    Checks that RepoStats verb works.
    """
    def setUp(self):
        StoragePoolTestCaseBase.setUp(self)

        #setup test variables
        self.sdUUID = self.client.newUUID()
        self.spUUID = self.client.newUUID()

        self.domainTarget1 = generateDomainTargets(self.client, self.mycfg["Connections"], [self.mycfg["Domain1"]])[0]

        #Create the tmp domain
        self.assertVdscOK(
            self.client.createStorageDomain(self.mycfg["StorageType1"], self.sdUUID,
                "Storage Domain 1", self.domainTarget1, self.mycfg["DomainClass1"]
            )
        )
        self.assertVdscOK(
            self.client.createStoragePool(self.spUUID, "Swimming Pool", self.sdUUID, [self.sdUUID], 1)
            )

        self.assertVdscOK(
            self.client.connectStoragePool(self.spUUID, self.mycfg["HostID1"], self.mycfg["Pool1Key"])
            )

    def test(self):
        self.assertVdscOK(self.client.repoStats())

class DestroyStoragePool(StoragePoolTestCaseBase):
    """
    Test that pool destruction works.
    """
    @classmethod
    def getConfigTemplate(cls):
        myExtraConf = {cls.__name__ : {
            "Domain2" : {"default" : "GUID, GUID", "validator" : Validate.list},
            "StorageType2": {"default" : "nfs", "validator" : eStorageType.parse},
            "DomainClass2" : {"default" : "data", "validator" : eDomainClass.parse},
            "Domain3" : {"default" : "GUID, GUID", "validator" : Validate.list},
            "StorageType3": {"default" : "nfs", "validator" : eStorageType.parse},
            "DomainClass3" : {"default" : "data", "validator" : eDomainClass.parse},
            }
        }
        myExtraConf[cls.__name__].update(__commonConfig__)
        return myExtraConf

    def setUp(self):
        StoragePoolTestCaseBase.setUp(self)

        #setup test variables
        domains = [self.mycfg["Domain1"], self.mycfg["Domain2"], self.mycfg["Domain3"]]
        self.domainTarget1, self.domainTarget2, self.domainTarget3 = generateDomainTargets(self.client, self.mycfg["Connections"], domains)

        self.sdUUID1 = self.client.newUUID()
        self.sdUUID2 = self.client.newUUID()
        self.sdUUID3 = self.client.newUUID()
        self.spUUID = self.client.newUUID()

        #Create the tmp domains
        self.assertVdscOK(
            self.client.createStorageDomain(self.mycfg["StorageType1"], self.sdUUID1,
                "Father", self.domainTarget1, self.mycfg["DomainClass1"]
            )
        )
        self.assertVdscOK(
            self.client.createStorageDomain(self.mycfg["StorageType2"], self.sdUUID2,
                "Son", self.domainTarget2, self.mycfg["DomainClass2"]
                )
        )
        self.assertVdscOK(
            self.client.createStorageDomain(self.mycfg["StorageType3"], self.sdUUID3,
                "Holy Spirit", self.domainTarget3, self.mycfg["DomainClass3"]
            )
        )

        poolName = "The Holy Trinity"
        self.assertVdscOK(
            self.client.createStoragePool(self.spUUID, poolName, self.sdUUID1, [self.sdUUID1, self.sdUUID2, self.sdUUID3], 1)
            )

        self.assertVdscOK(
            self.client.connectStoragePool(self.spUUID, self.mycfg["HostID1"], self.mycfg["Pool1Key"])
            )

        taskid = self.assertVdscOK(self.client.spmStart(self.spUUID, -1, -1, -1, False))['uuid']
        self.assertVdscTaskOK(self.client, taskid)

    def test(self):
        self.assertVdscOK(self.client.destroyStoragePool(self.spUUID, self.mycfg["HostID1"], self.mycfg["Pool1Key"]))

        self.assertVdscFail(
            self.client.getStoragePoolInfo(self.spUUID))

class DisconnectStoragePool(StoragePoolTestCaseBase):
    """
    Test that pool disconnection works.
    """
    @classmethod
    def getConfigTemplate(cls):
        myExtraConf = {cls.__name__ : {
            "Domain2" : {"default" : "GUID, GUID", "validator" : Validate.list},
            "StorageType2": {"default" : "nfs", "validator" : eStorageType.parse},
            "DomainClass2" : {"default" : "data", "validator" : eDomainClass.parse},
            "Domain3" : {"default" : "GUID, GUID", "validator" : Validate.list},
            "StorageType3": {"default" : "nfs", "validator" : eStorageType.parse},
            "DomainClass3" : {"default" : "data", "validator" : eDomainClass.parse},
            }
        }
        myExtraConf[cls.__name__].update(__commonConfig__)
        return myExtraConf

    def setUp(self):
        StoragePoolTestCaseBase.setUp(self)

        #setup test variables
        domains = [self.mycfg["Domain1"], self.mycfg["Domain2"], self.mycfg["Domain3"]]
        self.domainTarget1, self.domainTarget2, self.domainTarget3 = generateDomainTargets(self.client, self.mycfg["Connections"], domains)

        self.sdUUID1 = self.client.newUUID()
        self.sdUUID2 = self.client.newUUID()
        self.sdUUID3 = self.client.newUUID()
        self.spUUID = self.client.newUUID()

        #Create the tmp domains
        self.assertVdscOK(
            self.client.createStorageDomain(self.mycfg["StorageType1"], self.sdUUID1,
                "Logos", self.domainTarget1, self.mycfg["DomainClass1"]
            )
        )
        self.assertVdscOK(
            self.client.createStorageDomain(self.mycfg["StorageType2"], self.sdUUID2,
                "Thymos", self.domainTarget2, self.mycfg["DomainClass2"]
            )
        )
        self.assertVdscOK(
            self.client.createStorageDomain(self.mycfg["StorageType3"], self.sdUUID3,
                "Eros", self.domainTarget3, self.mycfg["DomainClass3"]
            )
        )

        poolName = "Plato's Three Parts of the Soul"
        self.assertVdscOK(
            self.client.createStoragePool(self.spUUID, poolName, self.sdUUID1, [self.sdUUID1, self.sdUUID2, self.sdUUID3], 1)
            )

        self.assertVdscOK(
            self.client.connectStoragePool(self.spUUID, self.mycfg["HostID1"], self.mycfg["Pool1Key"])
            )

    def test(self):
        self.assertVdscOK(self.client.disconnectStoragePool(self.spUUID, self.mycfg["HostID1"], self.mycfg["Pool1Key"]))

        self.assertVdscFail(
            self.client.getStoragePoolInfo(self.spUUID))

class ConnectToTheSamePoolMultipleTimesSimultaneously(StoragePoolTestCaseBase):
    """
    Try to connect to the same pool twice at the same time.
    """

    eConnectResult = Enum(Inconclusive=0, Failed=-1, Succeeded=1)
    @classmethod
    def getConfigTemplate(cls):
        myExtraConf = {cls.__name__ : {
            "NumberOfTimes" : {"default" : 3, "validator" : Validate.int},
            }
        }
        myExtraConf[cls.__name__].update(__commonConfig__)
        return myExtraConf

    def setUp(self):
        StoragePoolTestCaseBase.setUp(self)

        #setup test variables
        self.sdUUID = self.client.newUUID()
        self.spUUID = self.client.newUUID()

        self.domainTarget1 = generateDomainTargets(self.client, self.mycfg["Connections"], [self.mycfg["Domain1"]])[0]

        #Create the tmp domain
        self.assertVdscOK(
            self.client.createStorageDomain(self.mycfg["StorageType1"], self.sdUUID,
                "Storage Domain 1", self.domainTarget1, self.mycfg["DomainClass1"]
            )
        )

        self.assertVdscOK(
            self.client.createStoragePool(self.spUUID, "Swimming Pool", self.sdUUID, [self.sdUUID], 1)
            )
        self.results = [self.eConnectResult.Inconclusive] * self.mycfg["NumberOfTimes"]

    def _connect(self, threadNum):
        try:
            self.assertVdscOK(
                self.client.connectStoragePool(self.spUUID, self.mycfg["HostID1"], self.mycfg["Pool1Key"])
                )
            self.results[threadNum] = self.eConnectResult.Succeeded
        except:
            self.results[threadNum] = self.eConnectResult.Failed

    def test(self):
        self.threads = []
        for i in range(self.mycfg["NumberOfTimes"]):
            t = Thread(target = lambda: self._connect(i))
            t.start()
            self.threads.append(t)

        for t in self.threads:
            t.join()

        for result in self.results:
            self.assertEquals(result, self.eConnectResult.Succeeded)

class ConnectMultiplePools(StoragePoolTestCaseBase):
    """
    See that connecting to multiple pools on the same host fails.
    """
    @classmethod
    def getConfigTemplate(cls):
        myExtraConf = {cls.__name__ : {
            "Domain2" : {"default" : "GUID, GUID", "validator" : Validate.list},
            "StorageType2": {"default" : "nfs", "validator" : eStorageType.parse},
            "DomainClass2" : {"default" : "data", "validator" : eDomainClass.parse},
            "Pool2Key" : {"default" : "NFSKEY"},
            }
        }
        myExtraConf[cls.__name__].update(__commonConfig__)
        return myExtraConf

    def setUp(self):
        StoragePoolTestCaseBase.setUp(self)

        #setup test variables
        self.sdUUID1 = self.client.newUUID()
        self.sdUUID2 = self.client.newUUID()
        self.spUUID1 = self.client.newUUID()
        self.spUUID2 = self.client.newUUID()

        self.domainTarget1, self.domainTarget2 = generateDomainTargets(self.client, self.mycfg["Connections"],
            [self.mycfg["Domain1"], self.mycfg["Domain2"]])

        #Create the tmp domain
        self.assertVdscOK(
            self.client.createStorageDomain(self.mycfg["StorageType1"], self.sdUUID1,
                "Storage Domain 1", self.domainTarget1, self.mycfg["DomainClass1"]
            )
        )

        self.assertVdscOK(
            self.client.createStorageDomain(self.mycfg["StorageType2"], self.sdUUID2,
                "Storage Domain 2", self.domainTarget2, self.mycfg["DomainClass2"]
            )
        )

        self.assertVdscOK(
            self.client.createStoragePool(self.spUUID2, "Swimming Pool", self.sdUUID1, [self.sdUUID1], 1)
            )

        self.assertVdscOK(
            self.client.createStoragePool(self.spUUID1, "Pooling Pool", self.sdUUID2, [self.sdUUID2], 1)
            )

    def test(self):
        self.assertVdscOK(
            self.client.connectStoragePool(self.spUUID1, self.mycfg["HostID1"], self.mycfg["Pool1Key"])
            )
        self.assertVdscFail(
            self.client.connectStoragePool(self.spUUID2, self.mycfg["HostID1"], self.mycfg["Pool2Key"])
            )

class AttachTooManyDomains(StoragePoolTestCaseBase):
    @classmethod
    def getConfigTemplate(cls):
        return {cls.__name__ : {
                "VdsUri1" : {"default" : "http://server:54321"},
                "Connections" : {"default" : CONNECTIONS_OPTION_DEFAULT, "validator" : validateConnections},
                "PVs": {"validator" : Validate.list},
                "HostID1" : {"default" : 7, "validator" : Validate.int},
                "Pool1Key" : {"default" : "NFSKEY"},
                }
            }

    def setUp(self):
        StoragePoolTestCaseBase.setUp(self)
        self.domainTargets = generateDomainTargets(self.client, self.mycfg["Connections"], [[pv] for pv in self.mycfg["PVs"]])

        #setup test variables
        self.sdUUIDs = [self.client.newUUID() for i in self.mycfg["PVs"]]
        self.spUUID = self.client.newUUID()

    def test(self):
        #Create the domains
        for i in range(len(self.mycfg["PVs"])):
            sdUUID = self.sdUUIDs[i]
            target = self.domainTargets[i]
            self.assertVdscOK(
                self.client.createStorageDomain(eStorageType.iscsi, sdUUID,
                    "Storage Domain 1", target, vdsc.DATA_CLASS
                )
            )

        splitAt = 3

        #Create tmp pool
        self.assertVdscOK(
            self.client.createStoragePool(self.spUUID, "Swimming Pool", self.sdUUIDs[0], self.sdUUIDs[:splitAt], 1)
            )

        self.assertVdscOK(
            self.client.connectStoragePool(self.spUUID, self.mycfg["HostID1"], self.mycfg["Pool1Key"])
            )

        taskid = self.assertVdscOK(self.client.spmStart(self.spUUID, -1, -1, -1, False))['uuid']
        self.assertVdscTaskOK(self.client, taskid)

        try:
            for domain in self.sdUUIDs[splitAt:]:
                self.assertVdscOK(
                    self.client.attachStorageDomain(domain, self.spUUID)
                    )
        except:
            return

        self.fail("Managed to attach too many domains")




class PoolWithTooManyDomains(StoragePoolTestCaseBase):
    @classmethod
    def getConfigTemplate(cls):
        return {cls.__name__ : {
                "VdsUri1" : {"default" : "http://server:54321"},
                "Connections" : {"default" : CONNECTIONS_OPTION_DEFAULT, "validator" : validateConnections},
                "PVs": {"validator" : Validate.list},
                "HostID1" : {"default" : 7, "validator" : Validate.int},
                "Pool1Key" : {"default" : "NFSKEY"},
                }
            }

    def setUp(self):
        StoragePoolTestCaseBase.setUp(self)
        self.domainTargets = generateDomainTargets(self.client, self.mycfg["Connections"], [[pv] for pv in self.mycfg["PVs"]])

        #setup test variables
        self.sdUUIDs = [self.client.newUUID() for i in self.mycfg["PVs"]]
        self.spUUID = self.client.newUUID()

    def test(self):
        #Create the domains
        for i in range(len(self.mycfg["PVs"])):
            sdUUID = self.sdUUIDs[i]
            target = self.domainTargets[i]
            self.assertVdscOK(
                self.client.createStorageDomain(eStorageType.iscsi, sdUUID,
                    "Storage Domain 1", target, vdsc.DATA_CLASS
                )
            )

        #Create tmp pool
        self.assertVdscFail(
            self.client.createStoragePool(self.spUUID, "Swimming Pool", self.sdUUIDs[0], self.sdUUIDs, 1)
            )

class SetPoolDescription(StoragePoolTestCaseBase):
    def setUp(self):
        StoragePoolTestCaseBase.setUp(self)

        self.domainTarget1 = generateDomainTargets(self.client, self.mycfg["Connections"], [self.mycfg["Domain1"]])[0]

        #setup test variables
        self.sdUUID = self.client.newUUID()
        self.spUUID = self.client.newUUID()

        #Create the tmp domain
        self.assertVdscOK(
            self.client.createStorageDomain(self.mycfg["StorageType1"], self.sdUUID,
                "Storage Domain 1", self.domainTarget1, self.mycfg["DomainClass1"]
            )
        )

        #Create tmp pool
        self.assertVdscOK(
            self.client.createStoragePool(self.spUUID, "Swimming Pool", self.sdUUID, [self.sdUUID], 1)
            )

        self.assertVdscOK(
            self.client.connectStoragePool(self.spUUID, self.mycfg["HostID1"], self.mycfg["Pool1Key"])
            )

        taskid = self.assertVdscOK(self.client.spmStart(self.spUUID, -1, -1, -1, False))['uuid']
        self.assertVdscTaskOK(self.client, taskid)

    def testGoodDescription(self):
        desc = "Ve Ze Lo Keif"
        self.assertVdscOK(
            self.client.setStoragePoolDescription(self.spUUID, desc)
        )
        currentName = self.assertVdscOK(self.client.getStoragePoolInfo(self.spUUID))['info']['name']
        self.assertEquals(currentName, desc)

    def testLongDescription(self):
        desc = "KICK ME" * 100
        self.assertVdscFail(
            self.client.setStoragePoolDescription(self.spUUID, desc)
        )

class ConnectToPoolWithConnectionIssues(StoragePoolTestCaseBase):
    """
    Try to connect to a storage pool when the storage is disconnected for a
    few seconds.
    """
    def setUp(self):
        StoragePoolTestCaseBase.setUp(self)

        #setup test variables
        self.sdUUID = self.client.newUUID()
        self.spUUID = self.client.newUUID()

        self.domainTarget1 = generateDomainTargets(self.client, self.mycfg["Connections"], [self.mycfg["Domain1"]])[0]

        #Create the tmp domain
        self.assertVdscOK(
            self.client.createStorageDomain(self.mycfg["StorageType1"], self.sdUUID,
                "Storage Domain 1", self.domainTarget1, self.mycfg["DomainClass1"]
            )
        )

        self.assertVdscOK(
            self.client.createStoragePool(self.spUUID, "Swimming Pool", self.sdUUID, [self.sdUUID], 1)
            )

        self.connectFailed = False

    def _connectPool(self):
        try:
            self.assertVdscOK(
                self.client.connectStoragePool(self.spUUID, self.mycfg["HostID1"], self.mycfg["Pool1Key"])
                )
        except:
            self.connectFailed = True

    def test(self):
        connectThread = threading.Thread(target=self._connectPool)

        disconnectFromStorage(self.client, self.mycfg["Connections"])

        connectThread.start()

        time.sleep(5)

        connectToStorage(self.client, self.mycfg["Connections"])

        connectThread.join()
        self.assertFalse(self.connectFailed)

    def tearDown(self):
        connectToStorage(self.client, self.mycfg["Connections"])

        self.assertVdscOK(self.client.disconnectStoragePool(self.spUUID, self.mycfg["HostID1"], self.mycfg["Pool1Key"]))
        self.assertVdscOK(self.client.formatStorageDomain(self.sdUUID, True))

        destroyDomainTargets(self.client, [self.domainTarget1])

        StoragePoolTestCaseBase.tearDown(self)

class CreateStoragePoolWithOnedomain(StoragePoolTestCaseBase):
    """
    Create a storage pool with one domain.
    """
    def setUp(self):
        StoragePoolTestCaseBase.setUp(self)

        #setup test variables
        self.sdUUID = self.client.newUUID()
        self.spUUID = self.client.newUUID()

        self.domainTarget1 = generateDomainTargets(self.client, self.mycfg["Connections"], [self.mycfg["Domain1"]])[0]

        #Create the tmp domain
        self.assertVdscOK(
            self.client.createStorageDomain(self.mycfg["StorageType1"], self.sdUUID,
                "Storage Domain 1", self.domainTarget1, self.mycfg["DomainClass1"]
            )
        )

    def test(self):
        self.assertVdscOK(
            self.client.createStoragePool(self.spUUID, "Swimming Pool", self.sdUUID, [self.sdUUID], 1)
            )

        self.assertVdscOK(
            self.client.connectStoragePool(self.spUUID, self.mycfg["HostID1"], self.mycfg["Pool1Key"])
            )
        poolStatus = self.assertVdscOK(
            self.client.getStoragePoolInfo(self.spUUID))["info"]["pool_status"]
        self.assertEquals(poolStatus, ePoolStatus.Connected)

class CreateStoragePoolFail(StoragePoolTestCaseBase):
    def setUp(self):
        StoragePoolTestCaseBase.setUp(self)

        #setup test variables
        self.sdUUID = self.client.newUUID()
        self.spUUID = self.client.newUUID()

        self.domainTarget1 = generateDomainTargets(self.client, self.mycfg["Connections"], [self.mycfg["Domain1"]])[0]

        #Create the tmp domain
        self.assertVdscOK(
            self.client.createStorageDomain(self.mycfg["StorageType1"], self.sdUUID,
                "Storage Domain 1", self.domainTarget1, self.mycfg["DomainClass1"]
            )
        )

    def createWithInvalidDomain(self):
        self.assertVdscFail(
            self.client.createStoragePool(self.spUUID, "Twisting by the pool", self.sdUUID, [self.sdUUID, self.client.newUUID()], 1)
            )

    def createWithMasterdomainNotInList(self):
        self.assertVdscFail(
            self.client.createStoragePool(self.spUUID, "Twisting by the pool", self.sdUUID, [], 1)
            )

    def createWithInvlidUUID(self):
        self.assertVdscFail(
            self.client.createStoragePool("NotUUID", "Twisting by the pool", self.sdUUID, [self.sdUUID], 1)
            )

class ConnectStoragePoolFail(StoragePoolTestCaseBase):
    def setUp(self):
        StoragePoolTestCaseBase.setUp(self)

        #setup test variables
        self.sdUUID = self.client.newUUID()
        self.spUUID = self.client.newUUID()

        self.domainTarget1 = generateDomainTargets(self.client, self.mycfg["Connections"], [self.mycfg["Domain1"]])[0]
        self.agent1 = agentUtils.connectAgent(self.mycfg["VdsUri1"])


        #Create the tmp domain
        self.assertVdscOK(
            self.client.createStorageDomain(self.mycfg["StorageType1"], self.sdUUID,
                "Storage Domain 1", self.domainTarget1, self.mycfg["DomainClass1"]
            )
        )

    def test(self):
        self.assertVdscOK(
            self.client.createStoragePool(self.spUUID, "Swimming Pool", self.sdUUID, [self.sdUUID], 1)
            )

        for connection in self.mycfg["Connections"]:
            self.agent1.blockConnectionToHost(connection)

        self.assertVdscFail(
            self.client.connectStoragePool(self.spUUID, self.mycfg["HostID1"], self.mycfg["Pool1Key"])
            )

        for connection in self.mycfg["Connections"]:
            self.agent1.unblockConnectionToHost(connection)


def suite():
    tests = {
        CreateStoragePoolWithOnedomain : ["test"],
        CreateStoragePoolManyDomains : ["test"],
        CreateStoragePoolFail : ["createWithInvalidDomain",
                                 "createWithMasterdomainNotInList",
                                 "createWithInvlidUUID"],
        DisconnectStoragePool : ["test"],
        DestroyStoragePool : ["test"],
        ConnectMultiplePools : ["test"],
        ConnectToTheSamePoolMultipleTimesSimultaneously : ["test"],
        RepoStats : ["test"],
        DeactivateMaster : ["sameMasterVersion",
                            "higherMasterVersion",
                            "lastMaster"],
        ConnectToPoolWithConnectionIssues : ["test"],
        SetPoolDescription : ["testGoodDescription", "testLongDescription"],
        PoolWithTooManyDomains : ["test"],
        AttachTooManyDomains : ["test"],
        ConnectStoragePoolFail : ["test"]
    }

    resSuite = ut.TestSuite()
    for testcase, methods in tests.iteritems():
        resSuite.addTests(map(testcase, methods))

    return resSuite

validateConfig = lambda cfg : vdst.validateSuiteConfig(suite(), cfg)
